package com.jhh.pay.center.api;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Strings;
import com.jhh.pay.center.actor.ActorUtil;
import com.jhh.pay.center.actor.DeferredCompleteFunctional;
import com.jhh.pay.center.api.data.*;
import com.jhh.pay.center.model.*;
import com.jhh.pay.center.search.DocTransformer;
import com.jhh.pay.center.search.PagedList;
import com.jhh.pay.center.search.Searcher;
import com.jhh.pay.center.search.mapping.OrderMapping;
import com.jhh.pay.center.search.query.OrderQuery;
import com.jhh.pay.center.service.AppService;
import com.jhh.pay.center.service.OrderService;
import com.jhh.pay.center.service.PayChannelCfgService;
import com.jhh.pay.center.service.PayChannelService;
import com.jhh.pay.center.service.cloud.message.QueryResult;
import com.jhh.pay.center.service.cloud.message.TradeResult;
import com.jhh.pay.center.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;

import javax.servlet.ServletRequest;
import java.util.Map;
import java.util.TreeMap;


/**
 * @author tangxd
 * @Description: TODO
 * @date 2017/12/1
 */
@RestController
@RequestMapping("jhhpay/query")
public class QueryController extends AbstractController {

    @Autowired
    private AppService appService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private Searcher<OrderMapping> searcher;

    @Autowired
    private DocTransformer<Order, OrderR> transformer;

    @Autowired
    private PayChannelCfgService channelCfgService;

    @Autowired
    private PayChannelService channelService;

    @RequestMapping(value = "/1.0/state", method = RequestMethod.POST)
    DeferredResult<Result> state(
            @RequestBody StateRequest data,
            ServletRequest req
    ) {
        DeferredResult<Result> result = new DeferredResult<>();
        if (data.getAppId() <= 0) {
            result.setResult(new Result(TradeState.ERROR, null, "SYS:VLD1201", "appId非法"));
            return result;
        }
        if (Strings.isNullOrEmpty(data.getSid())) {
            result.setResult(new Result(TradeState.ERROR, null, "SYS:VLD1202", "流水号不能为空"));
            return result;
        }
        if (Integer.valueOf(data.getTs()).toString().length() != SECOND_INT_LENGTH) {
            result.setResult(new Result(TradeState.ERROR, null, "SYS:VLD1203", "时间戳错误"));
            return result;
        }
        if (Strings.isNullOrEmpty(data.getSign())) {
            result.setResult(new Result(TradeState.ERROR, null, "SYS:VLD1204", "验证码未填写"));
            return result;
        }

        App app = appService.get(data.getAppId());
        if (null == app) {
            result.setResult(new Result(TradeState.ERROR, null, "SYS:VLD1009", "appId不存在"));
            return result;
        }
//        String sign = Md5.encode(String.format("%d%s%d%s", data.getAppId(), data.getOrderNo(), data.getOrderTime(), app.getId()));
//        if (!sign.equals(data.getSign())) {
//            result.setResult(new Result(TradeState.ERROR, "SYS:VLD1010", "sign验证失败"));
//            return result;
//        }

        result = ActorUtil.deferred(
                "StateActor",
                "state-actor-" + StringUtils.random(10),
                data,
                config.getActorProcessTimeout(),
                (DeferredCompleteFunctional<TradeResult, Result>) (failure, response, r) -> {
                    if (response != null) {
                        r.setResult(new Result(getState(response.getState()), response.getSid(), response.getCode(), response.getMsg()));
                    } else {
                        r.setErrorResult(new Result(TradeState.ERROR, null, "SYS:TIMEOUT", "处理超时"));
                    }
                });
        return result;
    }


    @RequestMapping(value = "/1.0/order", method = RequestMethod.GET)
    DeferredResult<ResultT<OrderR>> getOrder(
            String sid,
            Integer app_id,
            String order_no
    ) {
        DeferredResult<ResultT<OrderR>> result = new DeferredResult<>();

        if(Strings.isNullOrEmpty(sid) && Strings.isNullOrEmpty(order_no)) {
            result.setResult(new ResultT<>("SYS:ORD1005", "sid和order_no必须输入一个", null));
            return result;
        }

        if (!Strings.isNullOrEmpty(sid)) {
            Order order = orderService.get(sid);
            if (order == null) {
                result.setResult(new ResultT<>("SYS:ORD1001", "订单不存在", null));
                return result;
            }
            OrderR r = transformer.transform(order);
            result.setResult(new ResultT<>(ResultT.SUCCESS, "获取成功", r));
            return result;
        }

        if (app_id == null || app_id <= 0) {
            result.setResult(new ResultT<>("SYS:ORD1002", "app_id错误", null));
            return result;
        }
        if (Strings.isNullOrEmpty(order_no)) {
            result.setResult(new ResultT<>("SYS:ORD1003", "order_no未填写", null));
            return result;
        }
        OrderQuery query = new OrderQuery();
        query.setAppId(app_id);
        query.setOrderNo(order_no);
        PagedList<OrderMapping> list = searcher.search(query);
        if (list.getTotal() == 0) {
            result.setResult(new ResultT<>("SYS:ORD1004", "订单不存在", null));
            return result;
        }
        Order order = orderService.get(list.getList().get(0).getId());
        result.setResult(new ResultT<>(ResultT.SUCCESS, "获取成功", transformer.transform(order)));
        return result;
    }

    @RequestMapping(value = "/1.0/channel/config")
    DeferredResult<ResultT> getChannelConfig(
            String channel_key,
            String ver,
            ServletRequest req
    ) {
        DeferredResult<ResultT> result = new DeferredResult<>();
        if (Strings.isNullOrEmpty(channel_key)) {
            result.setResult(new ResultT<>("SYS:CFG1001", "未提供channel_key参数", null));
            return result;
        }
        if (Strings.isNullOrEmpty(ver)) {
            result.setResult(new ResultT<>("SYS:CFG1002", "未提供ver参数", null));
            return result;
        }
        CfgRequest request = new CfgRequest();
        request.setChannelKey(channel_key);
        request.setVersion(ver);
        result = ActorUtil.deferred(
                "CfgActor",
                "cfg-actor-" + StringUtils.random(10),
                request,
                config.getActorProcessTimeout(),
                (DeferredCompleteFunctional<QueryResult<Map<String, Object>>, ResultT>) (failure, response, r) -> {
                    if (response != null) {
                        if (response.isSuccess()) {
                            r.setResult(new ResultT<>(ResultT.SUCCESS, "获取成功", response.getData()));
                        } else {
                            r.setErrorResult(new ResultT<>("SYS:CFG1004", response.getMsg(), null));
                        }
                    } else {
                        r.setErrorResult(new Result(TradeState.ERROR, null, "SYS:TIMEOUT", "处理超时"));
                    }
                });
        return result;
    }

    @RequestMapping(value = "/1.0/channel/config_values")
    DeferredResult<ResultT> getChannelConfigValues(
            String channel_key,
            String ver,
            ServletRequest req
    ) {
        DeferredResult<ResultT> result = new DeferredResult<>();
        if (Strings.isNullOrEmpty(channel_key)) {
            result.setResult(new ResultT<>("SYS:CFG1101", "未提供channel_key参数", null));
            return result;
        }
        if (Strings.isNullOrEmpty(ver)) {
            result.setResult(new ResultT<>("SYS:CFG1102", "未提供ver参数", null));
            return result;
        }

        PayChannel channel = channelService.getByKey(channel_key);
        if (channel == null) {
            result.setResult(new ResultT<>("SYS:CFG1103", "未提供ver参数", null));
            return result;
        }

        PayChannelCfg cfg = channelCfgService.get(channel.getId(), ver);
        if (cfg != null) {
            result.setResult(new ResultT<>(ResultT.SUCCESS, "success", JSON.parseObject(cfg.getCfg())));
            return result;
        }
        result.setResult(new ResultT<>("SYS:CFG1104", "配置不存在", null));
        return result;
    }

    @RequestMapping(value = "/1.0/search", method = RequestMethod.GET)
    DeferredResult<ResultT<PagedList<OrderR>>> getOrders(
    ) {
        return null;
    }
}
